/**
 * 
 */
package edu.arizona.bio5.onto.decomposition.locality;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom;
import org.semanticweb.owlapi.model.OWLAnnotationPropertyDomainAxiom;
import org.semanticweb.owlapi.model.OWLAnnotationPropertyRangeAxiom;
import org.semanticweb.owlapi.model.OWLAsymmetricObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLAxiomVisitor;
import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLDataPropertyDomainAxiom;
import org.semanticweb.owlapi.model.OWLDataPropertyExpression;
import org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom;
import org.semanticweb.owlapi.model.OWLDatatypeDefinitionAxiom;
import org.semanticweb.owlapi.model.OWLDeclarationAxiom;
import org.semanticweb.owlapi.model.OWLDifferentIndividualsAxiom;
import org.semanticweb.owlapi.model.OWLDisjointClassesAxiom;
import org.semanticweb.owlapi.model.OWLDisjointDataPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLDisjointObjectPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLDisjointUnionAxiom;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom;
import org.semanticweb.owlapi.model.OWLEquivalentDataPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLEquivalentObjectPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLFunctionalDataPropertyAxiom;
import org.semanticweb.owlapi.model.OWLFunctionalObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLHasKeyAxiom;
import org.semanticweb.owlapi.model.OWLInverseFunctionalObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLInverseObjectPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLIrreflexiveObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLNegativeDataPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLNegativeObjectPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLObjectPropertyDomainAxiom;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom;
import org.semanticweb.owlapi.model.OWLReflexiveObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLSameIndividualAxiom;
import org.semanticweb.owlapi.model.OWLSubAnnotationPropertyOfAxiom;
import org.semanticweb.owlapi.model.OWLSubClassOfAxiom;
import org.semanticweb.owlapi.model.OWLSubDataPropertyOfAxiom;
import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom;
import org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom;
import org.semanticweb.owlapi.model.OWLSymmetricObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom;
import org.semanticweb.owlapi.model.SWRLRule;

import uk.ac.manchester.cs.util.SetUtils;

import com.clarkparsia.owlapi.modularity.locality.LocalityClass;

/**
 * Given an OWL axiom alpha and a signature S, computes all
 * minimal (w.r.t. inclusion) subsets S' of S, s.t.
 * alpha is non-local w.r.t. S'
 * (in other words, alpha will appear in a module for S' but
 * not in a module for any proper subset of S')
 * 
 * @author Pavel Klinov
 * 
 * 
 *
 */
public class NonSyntLocalAxiomSignatureFinder implements NonLocalAxiomSignatureFinder, OWLAxiomVisitor {

	private static final Set<OWLEntity> EMPTY_SIG = Collections.emptySet(); 
	
	private LocalityClass m_localClass = null;
	private Collection<? extends OWLEntity> m_sig = null;
	private Collection<Set<OWLEntity>> m_minSubsigs = null;
	
	public NonSyntLocalAxiomSignatureFinder(LocalityClass lClass) {
		
		m_minSubsigs = new ArrayList<Set<OWLEntity>>();
		m_localClass = lClass;
	}
	
	public Collection<Set<OWLEntity>> findMinimalSeedSignatures(OWLAxiom axiom, Collection<? extends OWLEntity> baseSig) {
		
		m_sig = baseSig;
		m_minSubsigs.clear();
		axiom.accept(this);
		
		return m_minSubsigs;
	}
	
	@Override
	public void visit(OWLAnnotationAssertionAxiom axiom) {
		//Annotations are always local, return the empty set
	}

	@Override
	public void visit(OWLSubAnnotationPropertyOfAxiom axiom) {
		//Annotations are always local, return the empty set
	}

	@Override
	public void visit(OWLAnnotationPropertyDomainAxiom axiom) {
		//Annotations are always local, return the empty set
	}

	@Override
	public void visit(OWLAnnotationPropertyRangeAxiom axiom) {
		//Annotations are always local, return the empty set
	}

	@Override
	public void visit(OWLDeclarationAxiom axiom) {
		
	}

	
	@Override
	public void visit(OWLSubClassOfAxiom axiom) {
		//Find all maximal subsignatures S s.t. either the subclass is not in Bot(S) AND 
		//the superclass is not in Top(S)
		m_minSubsigs = new BottomNonEquivFinder(m_localClass).findMinimalSignatures(axiom.getSubClass(), m_sig);
		m_minSubsigs = SetUtils.unionAllAndMinimizeWrtInclusion(new TopNonEquivFinder(m_localClass).findMinimalSignatures(axiom.getSuperClass(), m_sig), m_minSubsigs);
	}



	@Override
	public void visit(OWLNegativeObjectPropertyAssertionAxiom axiom) {

		switch(m_localClass) {
		
		case TOP_TOP: 
			//The axiom is non-local w.r.t. any signature
			LocalityUtils.saveEmptySignature(m_minSubsigs);
			break;
        case BOTTOM_BOTTOM:
        case TOP_BOTTOM:
        	//The axiom is local w.r.t. all names except of the property's name
        	//Save the property name if it is contained in the signature
        	LocalityUtils.saveName(axiom.getProperty().getNamedProperty(), m_sig, m_minSubsigs);
		}
	}


	@Override
	public void visit(OWLAsymmetricObjectPropertyAxiom axiom) {

		
		
		switch (m_localClass) {
		
        case BOTTOM_BOTTOM:
        case TOP_BOTTOM:
            //Here the axiom is always local, so return the empty set
            break;
        case TOP_TOP:
        	//The axiom is always non-local here
        	LocalityUtils.saveEmptySignature(m_minSubsigs);
		}		
	}

	@Override
	public void visit(OWLReflexiveObjectPropertyAxiom axiom) {
		// The axiom is non-local if the signature contains the property name
		// Saves the singleton subsignature
		LocalityUtils.saveName(axiom.getProperty().getNamedProperty(), m_sig, m_minSubsigs);
	}

	@Override
	public void visit(OWLDisjointClassesAxiom axiom) {
		
		if (axiom.getClassExpressions().size() <= 1) return;
		//Split this up onto binary subclass axioms
		List<OWLClassExpression> classes = axiom.getClassExpressionsAsList();
		OWLDataFactory factory = OWLManager.createOWLOntologyManager().getOWLDataFactory();
		
		for (int i = 0; i < classes.size() - 1; i++) {
			
			for (int j = i + 1; j < classes.size(); j++) {
				
				NonSyntLocalAxiomSignatureFinder finder = new NonSyntLocalAxiomSignatureFinder(m_localClass);
				Collection<Set<OWLEntity>> minSigs = 	finder.findMinimalSeedSignatures(
															factory.getOWLSubClassOfAxiom(classes.get(i),
																	factory.getOWLObjectComplementOf(classes.get(j))),
															m_sig);
				
				if (i == 0 && j == 1) {
					
					m_minSubsigs.addAll(minSigs);
					
				} else {
					
					SetUtils.addAllandMinimizeWrtInclusion(minSigs, m_minSubsigs);
				}
				//Break out if we got the empty signature
				if (m_minSubsigs.contains(EMPTY_SIG)) return;
			}
		}
	}

	@Override
	public void visit(OWLDataPropertyDomainAxiom axiom) {

		switch (m_localClass) {
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is non-local if the data property is in the signature AND
			// the property's domain is *not* in Top(S)
			if (m_sig.contains(axiom.getProperty().asOWLDataProperty())) {
			
				m_minSubsigs = 	new TopNonEquivFinder(m_localClass).findMinimalSignatures(axiom.getDomain(), m_sig);
				m_minSubsigs = 	SetUtils.unionAndMinimizeWrtInclusion(
								m_minSubsigs, LocalityUtils.getSingletonSignature(axiom.getProperty().asOWLDataProperty()));
			}
			break;
		case TOP_TOP:
			// Here the axiom is non-local if the property's domain is not in Top(S)
			m_minSubsigs = new TopNonEquivFinder(m_localClass).findMinimalSignatures(axiom.getDomain(), m_sig);
			break;
		}
	}


	@Override
	public void visit(OWLObjectPropertyDomainAxiom axiom) {
		// Basically the same as the one above
		switch (m_localClass) {
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is non-local if the data property is in the signature AND
			// the property's domain is *not* in Top(S)
			if (m_sig.contains(axiom.getProperty().getNamedProperty())) {
			
				m_minSubsigs = 	new TopNonEquivFinder(m_localClass).findMinimalSignatures(axiom.getDomain(), m_sig);
				m_minSubsigs = 	SetUtils.unionAndMinimizeWrtInclusion(
								m_minSubsigs, LocalityUtils.getSingletonSignature(axiom.getProperty().getNamedProperty()));
			}
			break;
		case TOP_TOP:
			// Here the axiom is non-local if the property's domain is not in Top(S)
			m_minSubsigs = new TopNonEquivFinder(m_localClass).findMinimalSignatures(axiom.getDomain(), m_sig);			
			break;
		}		
	}

	@Override
	public void visit(OWLEquivalentObjectPropertiesAxiom axiom) {
		// The axiom is non-local w.r.t. all subsignatures that contain at least one property
		// Save the set of property names contained in the signature
		if (axiom.getProperties().size() > 1) {
			
			for (OWLObjectPropertyExpression property : axiom.getProperties()) {
				
				LocalityUtils.saveName(property.getNamedProperty(), m_sig, m_minSubsigs);
			}
		}
	}

	@Override
	public void visit(OWLNegativeDataPropertyAssertionAxiom axiom) {
		 
		switch(m_localClass) {
		
		case TOP_BOTTOM:
		case BOTTOM_BOTTOM:
			// Here the axiom is non-local w.r.t. all signatures that contain the property name
			// Save the name as a singleton signature if it is contained
			LocalityUtils.saveName(axiom.getProperty().asOWLDataProperty(), m_sig, m_minSubsigs);
			break;
		case TOP_TOP:
			// Here the axiom is always non-local
			LocalityUtils.saveEmptySignature(m_minSubsigs);
		}
	}

	@Override
	public void visit(OWLDifferentIndividualsAxiom axiom) {
		// This is always local, so save nothing
	}

	@Override
	public void visit(OWLDisjointDataPropertiesAxiom axiom) {

		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is non-local w.r.t. all subsignatures that contain
			// more than property occurring in the axiom
			// First collect all properties that are contained in the signature
			List<OWLEntity> names = new ArrayList<OWLEntity>();
			
			for (OWLDataPropertyExpression prop : axiom.getProperties()) {
				
				if (m_sig.contains(prop.asOWLDataProperty())) names.add(prop.asOWLDataProperty());
			}
			//Now save all pairs
			LocalityUtils.saveAllPairs(names, m_minSubsigs);
			break;
		case TOP_TOP:
			// Here the axiom is always non-local
			LocalityUtils.saveEmptySignature(m_minSubsigs);
		}
	}


	@Override
	public void visit(OWLDisjointObjectPropertiesAxiom axiom) {
		// Same as the previous on
		// Btw, I do hate copy-paste but can't see an easy way to get rid of it
		// It'd have been so much better if we had a generic way of getting a name for a property expression
		
		
		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is non-local w.r.t. all subsignatures that contain
			// more than property occurring in the axiom
			// First collect all properties that are contained in the signature
			List<OWLEntity> names = new ArrayList<OWLEntity>();
			
			for (OWLObjectPropertyExpression prop : axiom.getProperties()) {
				
				if (m_sig.contains(prop.getNamedProperty())) names.add(prop.getNamedProperty());
			}
			//Now save all pairs
			LocalityUtils.saveAllPairs(names, m_minSubsigs);
			break;
		case TOP_TOP:
			// Here the axiom is always non-local
			LocalityUtils.saveEmptySignature(m_minSubsigs);
		}
	}

	@Override
	public void visit(OWLObjectPropertyRangeAxiom axiom) {
		
		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is non-local w.r.t. all signatures S such that 
			// S contains the property's name *and* the range is not in Top(S)
			if (m_sig.contains(axiom.getProperty().getNamedProperty())) {
				
				m_minSubsigs =	new TopNonEquivFinder(m_localClass).findMinimalSignatures(axiom.getRange(), m_sig);	
				m_minSubsigs = 	SetUtils.unionAndMinimizeWrtInclusion(
									m_minSubsigs, LocalityUtils.getSingletonSignature(axiom.getProperty().getNamedProperty()));
			}
			break;
		case TOP_TOP:
			// Here we have only the second condition from above
			m_minSubsigs = new TopNonEquivFinder(m_localClass).findMinimalSignatures(axiom.getRange(), m_sig);
		}
	}

	@Override
	public void visit(OWLObjectPropertyAssertionAxiom axiom) {

		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is always non-local
			LocalityUtils.saveEmptySignature(m_minSubsigs);
			break;
		case TOP_TOP:
			// Here the axiom is non-local w.r.t. only signatures that contain the property's name
			LocalityUtils.saveName(axiom.getProperty().getNamedProperty(), m_sig, m_minSubsigs);
		}		
	}

	@Override
	public void visit(OWLFunctionalObjectPropertyAxiom axiom) {
		
		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is non-local w.r.t. only signatures that contain the property's name
			LocalityUtils.saveName(axiom.getProperty().getNamedProperty(), m_sig, m_minSubsigs);
			break;
		case TOP_TOP:
			// Here the axiom is always non-local
			LocalityUtils.saveEmptySignature(m_minSubsigs);		
		}
	}

	@Override
	public void visit(OWLSubObjectPropertyOfAxiom axiom) {

		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is non-local w.r.t. only signatures that contain the subproperty's name
			LocalityUtils.saveName(axiom.getSubProperty().getNamedProperty(), m_sig, m_minSubsigs);
			break;
		case TOP_TOP:
			// Here the axiom is non-local w.r.t. only signatures that contain the subproperty's name
			LocalityUtils.saveName(axiom.getSuperProperty().getNamedProperty(), m_sig, m_minSubsigs);			
		}
	}

	@Override
	public void visit(OWLDisjointUnionAxiom axiom) {
		//
		if (axiom.getClassExpressions().size() <= 1) return;
		//Split this up into an n-ary disjoint axiom and a single equivalence axiom
		axiom.getOWLDisjointClassesAxiom().accept(this);
		
		if (!m_minSubsigs.contains(EMPTY_SIG)) {
			
			axiom.getOWLEquivalentClassesAxiom().accept(this);
		}
	}

	@Override
	public void visit(OWLSymmetricObjectPropertyAxiom axiom) {
		// The axiom is non-local w.r.t. signatures containing the property's name
		LocalityUtils.saveName(axiom.getProperty().getNamedProperty(), m_sig, m_minSubsigs);
	}

	@Override
	public void visit(OWLDataPropertyRangeAxiom axiom) {

		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is non-local w.r.t. all signatures S such that 
			// S contains the property's name *and* the range is not a Top datatype
			if (!axiom.getRange().isTopDatatype())	LocalityUtils.saveName(axiom.getProperty().asOWLDataProperty(), m_sig, m_minSubsigs);
			
			break;
		case TOP_TOP:
			// Here we have only the second condition from above
			if (!axiom.getRange().isTopDatatype()) {
				//Such axiom is always non-local
				LocalityUtils.saveEmptySignature(m_minSubsigs);
			}
		}
	}

	@Override
	public void visit(OWLFunctionalDataPropertyAxiom axiom) {

		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is non-local w.r.t. all signatures that contain the property's name
			LocalityUtils.saveName(axiom.getProperty().asOWLDataProperty(), m_sig, m_minSubsigs);
			
			break;
		case TOP_TOP:
			// The axiom is always non-local here
			LocalityUtils.saveEmptySignature(m_minSubsigs);
		}
	}

	@Override
	public void visit(OWLEquivalentDataPropertiesAxiom axiom) {
		// The axiom is non-local w.r.t. all signatures that contain the name of at least one data property
		// (unless the cardinality is one)
		// Save the names of the properties which occur in the signature
		if (axiom.getProperties().size() > 1) {
			
			for (OWLDataPropertyExpression property : axiom.getProperties()) {
				
				LocalityUtils.saveName(property.asOWLDataProperty(), m_sig, m_minSubsigs);
			}
		}
	}

	@Override
	public void visit(OWLClassAssertionAxiom axiom) {
		// The axiom is non-local for all signatures S such that the class is not in Top(S)
		m_minSubsigs = new TopNonEquivFinder(m_localClass).findMinimalSignatures(axiom.getClassExpression(), m_sig);
	}

	@Override
	public void visit(OWLEquivalentClassesAxiom axiom) {
		
		if (axiom.getClassExpressions().size() <= 1) return;
		
		List<OWLClassExpression> classes = axiom.getClassExpressionsAsList();		
		//Split this up into binary subclass axioms
		OWLDataFactory factory = OWLManager.createOWLOntologyManager().getOWLDataFactory();
		
		for (int i = 0; i < classes.size() - 1; i++) {
			
			for (int j = i + 1; j < classes.size(); j++) {
				
				NonSyntLocalAxiomSignatureFinder finder = new NonSyntLocalAxiomSignatureFinder(m_localClass);
				
				Collection<Set<OWLEntity>> minSigs = 	finder.findMinimalSeedSignatures(
															factory.getOWLSubClassOfAxiom(classes.get(i), classes.get(j)),
															m_sig);
				
				if (i == 0 && j == 1) {
					
					m_minSubsigs.addAll(minSigs);
					
				} else {
					
					SetUtils.addAllandMinimizeWrtInclusion(minSigs, m_minSubsigs);
				}
				
				minSigs = finder.findMinimalSeedSignatures(factory.getOWLSubClassOfAxiom(classes.get(j), classes.get(i)), m_sig);
				SetUtils.addAllandMinimizeWrtInclusion(minSigs, m_minSubsigs);
				//Break out if we got the empty signature
				if (m_minSubsigs.contains(EMPTY_SIG)) return;
			}
		}		
	}

	@Override
	public void visit(OWLDataPropertyAssertionAxiom axiom) {

		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is non-local w.r.t. all signatures
			LocalityUtils.saveEmptySignature(m_minSubsigs);
			break;
		case TOP_TOP:
			// The axiom is non-local w.r.t. signatures that contain its name
			LocalityUtils.saveName(axiom.getProperty().asOWLDataProperty(), m_sig, m_minSubsigs);
		}
	}

	@Override
	public void visit(OWLTransitiveObjectPropertyAxiom axiom) {
		// The axiom is non-local w.r.t. signatures that contain the name of the property
		LocalityUtils.saveName(axiom.getProperty().getNamedProperty(), m_sig, m_minSubsigs);
	}

	@Override
	public void visit(OWLIrreflexiveObjectPropertyAxiom axiom) {

		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// Here the axiom is always local since the empty property is irreflexive
			break;
		case TOP_TOP:
			// The axiom is always non-local
			LocalityUtils.saveEmptySignature(m_minSubsigs);
		}
	}

	@Override
	public void visit(OWLSubDataPropertyOfAxiom axiom) {

		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// The axiom is non-local w.r.t. signatures that contain the name of the sub property
			LocalityUtils.saveName(axiom.getSubProperty().asOWLDataProperty(), m_sig, m_minSubsigs);
			break;
		case TOP_TOP:
			// The axiom is non-local w.r.t. signatures that contain the name of the super property
			LocalityUtils.saveName(axiom.getSuperProperty().asOWLDataProperty(), m_sig, m_minSubsigs);
		}		
	}

	@Override
	public void visit(OWLInverseFunctionalObjectPropertyAxiom axiom) {

		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// The axiom is non-local w.r.t. signatures that contain the name of the property
			LocalityUtils.saveName(axiom.getProperty().getNamedProperty(), m_sig, m_minSubsigs);
			break;
		case TOP_TOP:
			// The axiom is always non-local
			LocalityUtils.saveEmptySignature(m_minSubsigs);
		}		
	}

	@Override
	public void visit(OWLSameIndividualAxiom axiom) {
		// The axiom is always local
	}

	@Override
	public void visit(OWLSubPropertyChainOfAxiom axiom) {

		switch(m_localClass) {
		
		case BOTTOM_BOTTOM:
		case TOP_BOTTOM:
			// The axiom is non-local w.r.t. all signatures S which
			// contain all properties in the chain (i.e. no property is in Bot(S)) 
			Set<OWLEntity> names = new HashSet<OWLEntity>();
			
			for (OWLObjectPropertyExpression prop : axiom.getPropertyChain()) names.add(prop.getNamedProperty());
			
			if (m_sig.containsAll(names)) m_minSubsigs.add(names);

			break;
		case TOP_TOP:
			// The axiom is non-local w.r.t. all signatures S which contain the RHS
			LocalityUtils.saveName(axiom.getSuperProperty().getNamedProperty(), m_sig, m_minSubsigs);
		}
	}

	@Override
	public void visit(OWLInverseObjectPropertiesAxiom axiom) {
		// The axiom is non-local w.r.t. all signatures S s.t.
		// S contains either the first property or the second
		LocalityUtils.saveName(axiom.getFirstProperty().getNamedProperty(), m_sig, m_minSubsigs);
		LocalityUtils.saveName(axiom.getSecondProperty().getNamedProperty(), m_sig, m_minSubsigs);
	}

	@Override
	public void visit(OWLHasKeyAxiom axiom) {
		//Treat it as a local axiom
	}

	@Override
	public void visit(OWLDatatypeDefinitionAxiom axiom) {
		//Treat it as a local axiom
	}

	@Override
	public void visit(SWRLRule axiom) {
		// The axiom is always non-local
		LocalityUtils.saveEmptySignature(m_minSubsigs);
	}
}
